from django.core.exceptions import ObjectDoesNotExist
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny, IsAuthenticated
from django.utils import timezone
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from rest_framework_simplejwt.authentication import JWTAuthentication

from .models import Package, Privilege
from .serializers import PackageSerializer
from ..utils.pageNumberPagination import CustomPageNumberPagination
from ..utils.response_utils import api_response, ResponseCode


class ListPackageView(APIView):
    """
    获取套餐列表接口
    """
    permission_classes = [AllowAny]
    authentication_classes = []

    @swagger_auto_schema(
        operation_description="获取套餐列表",
        responses={
            200: openapi.Response(
                description="获取成功",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'code': openapi.Schema(type=openapi.TYPE_INTEGER),
                        'msg': openapi.Schema(type=openapi.TYPE_STRING),
                        'data': openapi.Schema(
                            type=openapi.TYPE_ARRAY,
                            items=openapi.Schema(
                                type=openapi.TYPE_OBJECT,
                                properties={
                                    'id': openapi.Schema(type=openapi.TYPE_STRING),
                                    'name': openapi.Schema(type=openapi.TYPE_STRING),
                                    'price': openapi.Schema(type=openapi.TYPE_NUMBER),
                                    'durations': openapi.Schema(
                                        type=openapi.TYPE_ARRAY,
                                        items=openapi.Schema(type=openapi.TYPE_OBJECT)
                                    ),
                                    'privileges': openapi.Schema(
                                        type=openapi.TYPE_ARRAY,
                                        items=openapi.Schema(type=openapi.TYPE_OBJECT)
                                    ),
                                    'status': openapi.Schema(type=openapi.TYPE_BOOLEAN),
                                    'create_time': openapi.Schema(type=openapi.TYPE_STRING, format="date-time"),
                                    'update_time': openapi.Schema(type=openapi.TYPE_STRING, format="date-time"),
                                }
                            )
                        )
                    }
                )
            ),
            400: openapi.Response(description="无效的参数"),
        },
        tags=["套餐管理"]
    )
    def get(self, request, *args, **kwargs):
        try:
            queryset = Package.objects.all().order_by('-create_time')
            if not queryset.exists():
                return api_response(ResponseCode.NOT_FOUND, "未找到套餐", data=[])

            serializer = PackageSerializer(queryset, many=True)

            return api_response(ResponseCode.SUCCESS, "获取套餐列表成功", serializer.data)
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, f"系统内部错误{e}")


class CreatePackageView(APIView):
    """
    创建套餐接口
    """
    permission_classes = [AllowAny]
    authentication_classes = [JWTAuthentication]

    @swagger_auto_schema(
        operation_description="创建套餐",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'name': openapi.Schema(type=openapi.TYPE_STRING, description='套餐名称'),
                'price': openapi.Schema(type=openapi.TYPE_NUMBER, description='套餐价格'),
                'duration': openapi.Schema(type=openapi.TYPE_STRING, description='时长（月度monthly、季度quarter、年度yearly）'),
                'privileges': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_STRING),
                                             description='特权名称列表'),
                'status': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='套餐状态'),
                'recommend': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='是否推荐'),
            }
        ),
        responses={
            200: openapi.Response(
                description="创建成功",
                schema=PackageSerializer,
            ),
            400: openapi.Response(description="参数错误"),
        },
        tags=["套餐管理"]
    )
    def post(self, request, *args, **kwargs):
        """
        创建套餐
        """
        package_data = request.data

        # 校验特权是否存在，并处理特权列表
        privilege_names = package_data.get('privileges', [])
        privileges = []
        for privilege_name in privilege_names:
            privilege, created = Privilege.objects.get_or_create(name=privilege_name)
            privileges.append(privilege)

        # 创建套餐对象
        package = Package.objects.create(
            name=package_data['name'],
            price=package_data['price'],
            duration=package_data['duration'],
            status=package_data.get('status', True),
            recommend=package_data.get('recommend', False)
        )
        package.privileges.set(privileges)

        # 返回成功响应
        return api_response(ResponseCode.SUCCESS, "创建套餐成功", data=PackageSerializer(package).data)


class RetrievePackageView(APIView):
    """
    获取套餐详情接口
    """
    permission_classes = [AllowAny]
    authentication_classes = []

    @swagger_auto_schema(
        operation_description="获取套餐详情",
        manual_parameters=[
            openapi.Parameter('package_id', openapi.IN_PATH, description="套餐ID", type=openapi.TYPE_STRING)
        ],
        responses={
            200: openapi.Response(
                description="获取成功",
                schema=PackageSerializer
            ),
            404: openapi.Response(description="套餐不存在")
        },
        tags=["套餐管理"]
    )
    def get(self, request, package_id, *args, **kwargs):
        try:
            package = Package.objects.get(id=package_id)
        except ObjectDoesNotExist:
            return api_response(ResponseCode.NOT_FOUND, "套餐不存在")
        serializer = PackageSerializer(package)
        return api_response(ResponseCode.SUCCESS, "获取套餐详情成功", serializer.data)


class UpdatePackageView(APIView):
    """
    更新套餐接口
    """
    permission_classes = [AllowAny]
    authentication_classes = [JWTAuthentication]

    @swagger_auto_schema(
        operation_description="更新套餐",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'name': openapi.Schema(type=openapi.TYPE_STRING, description='套餐名称'),
                'price': openapi.Schema(type=openapi.TYPE_NUMBER, description='套餐价格'),
                'duration': openapi.Schema(type=openapi.TYPE_STRING, description='时长（月度monthly、季度quarter、年度yearly）'),
                'privileges': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_STRING),
                                             description='特权名称列表'),
                'status': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='套餐状态'),
                'recommend': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='是否推荐'),
            }
        ),
        responses={
            200: openapi.Response(
                description="修改成功",
                schema=PackageSerializer,
            ),
            400: openapi.Response(description="参数错误"),
            404: openapi.Response(description="套餐未找到"),
        },
        tags=["套餐管理"]
    )
    def put(self, request, *args, **kwargs):
        """
        更新套餐
        """
        package_id = kwargs.get('package_id')
        try:
            package = Package.objects.get(id=package_id)
        except ObjectDoesNotExist:
            return api_response(ResponseCode.NOT_FOUND, "套餐未找到")

        package_data = request.data

        # 更新套餐对象
        package.name = package_data.get('name', package.name)
        package.price = package_data.get('price', package.price)
        package.duration = package_data.get('duration', package.duration)
        package.status = package_data.get('status', package.status)
        package.recommend = package_data.get('recommend', package.recommend)

        # 处理特权列表
        privilege_names = package_data.get('privileges', [])
        privileges = []
        for privilege_name in privilege_names:
            privilege, created = Privilege.objects.get_or_create(name=privilege_name)
            privileges.append(privilege)
        package.privileges.set(privileges)

        package.save()

        # 返回成功响应
        return api_response(ResponseCode.SUCCESS, "更新套餐成功", data=PackageSerializer(package).data)


class DeletePackageView(APIView):
    """
    删除套餐接口
    """
    permission_classes = [AllowAny]
    authentication_classes = [JWTAuthentication]

    @swagger_auto_schema(
        operation_description="删除套餐",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['package_ids'],
            properties={
                'package_ids': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_STRING),
                                              description="套餐ID列表"),
            }
        ),
        responses={
            200: openapi.Response(description="删除成功"),
            404: openapi.Response(description="套餐不存在")
        },
        tags=["套餐管理"]
    )
    def delete(self, request, *args, **kwargs):
        package_ids = request.data.get('package_ids')
        if not package_ids or not isinstance(package_ids, list):
            return api_response(ResponseCode.BAD_REQUEST, "参数错误")
        not_found_ids = []
        for package_id in package_ids:
            try:
                package = Package.objects.get(id=package_id)
                package.delete()
            except ObjectDoesNotExist:
                not_found_ids.append(package_id)
        if not_found_ids:
            return api_response(ResponseCode.NOT_FOUND,
                                f"成功删除套餐{len(package_ids) - len(not_found_ids)}个，未删除套餐{not_found_ids}个")
        return api_response(ResponseCode.SUCCESS, "删除套餐成功")

